/**
 * Project Name:fastPlat
 * File Name:SysLogInterceptor.java
 * Package Name:com.fast.intercept
 * Date:2015年3月5日下午10:51:24
 * Copyright (c) 2015, lsflu@126.com All Rights Reserved.
 *
*/

package com.fast.cms.web.interceptor;

import java.lang.reflect.Method;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.fast.base.model.AnoSysLog;
import com.fast.base.util.BeanUtil;
import com.fast.base.util.DateUtils;
import com.fast.base.util.LogUtils;
import com.fast.base.util.web.IPUtils;
import com.fast.base.util.web.NetworkUtil;
import com.fast.base.util.web.WebUtil;
import com.fast.cms.service.system.SysLogService;
import com.fast.user.model.admin.AdminUser;
import com.fast.user.model.admin.SysLog;
import com.fast.user.model.member.Member;

/**
 * ClassName:SysLogInterceptor <br/>
 * 用途: 日志拦截器 <br/>
 * 开发人员：lushuifa  http://lushuifa.iteye.com/
 * 邮箱:lsflu@126.com
 * @version  
 * @since    JDK 1.6
 * @see
 * Date:     2015年3月5日 下午10:51:24 <br/> 	 
 */
public class SysLogInterceptor implements HandlerInterceptor {
	
	
	
	
	@Resource(name="sysLogService")
	protected SysLogService logS;

	/** 
	 * 第一执行
     * 在业务处理器处理请求之前被调用  
     * 如果返回false  
     *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链  
     * 如果返回true  
     *    执行下一个拦截器,直到所有的拦截器都执行完毕  
     *    再执行被拦截的Controller  
     *    然后进入拦截器链,  
     *    从最后一个拦截器往回执行所有的postHandle()  
     *    接着再从最后一个拦截器往回执行所有的afterCompletion()  
     */  

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
			Object object) throws Exception {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		return true;
	}
	
	/**
	 * 第二执行
	 * 在业务处理器处理请求执行完成后,生成视图之前执行的动作  
	 * TODO 简单描述该方法的实现功能（可选）.
	 * @see org.springframework.web.servlet.HandlerInterceptor#postHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView)
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response,
			Object object, ModelAndView modelAndView) throws Exception {
		try{
			String path     = request.getContextPath();
			String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
			if(request.getServerPort()==80){
				basePath = request.getScheme()+"://"+request.getServerName()+path+"/";
			}
			String uri = request.getRequestURL().toString();
			LogUtils.info("url处理前："+uri);
			uri = uri.replace("http://", "").replace("//", "/");
			uri  = uri.replace(basePath.replace("http://", ""), "");
			if(uri.contains(".do")){
				String url = uri;
				LogUtils.info("url处理后："+url);
		    	String mappingUrl = url.substring(0, url.lastIndexOf("/"));
		    	LogUtils.info("得到的mappingUrl名字为："+mappingUrl);
		    	String methodName     = url.split("/")[1];
		    	Class<?>  controllerClazz = null;
		    	Set<Class<?>> classSet = BeanUtil.getClasses("com.fast.cms.web.controller");
		    	Set<Class<?>> classSet1 = BeanUtil.getClasses("com.fast.cms.web.mobile");
		    	Set<Class<?>> classSet2 = BeanUtil.getClasses("com.fast.user.web.controller");
		    	Set<Class<?>> classSet3 = BeanUtil.getClasses("com.fast.office.web.controller");
		    	classSet.addAll(classSet1);
		    	classSet.addAll(classSet2);
		    	classSet.addAll(classSet3);
		    	for (Class<?> clazz : classSet) {
		    		RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);
		    		if(null!=requestMapping){
		    			String dmzPath = requestMapping.value()[0];
			    		if(dmzPath.contains(mappingUrl)){
			    			controllerClazz = clazz;
			    		}
		    		}
				}
		    	
		    	if(null!=controllerClazz){
		    		LogUtils.info("得到的controllerClazz名字为："+controllerClazz.getName());
			    	Method[] methods = controllerClazz.getMethods();
			    	for (int i = 0; i < methods.length; i++) {
			    		AnoSysLog anoSysLog= methods[i].getAnnotation(AnoSysLog.class);
			    		RequestMapping requestMapping = methods[i].getAnnotation(RequestMapping.class);
			    		if(requestMapping!=null&&anoSysLog!=null){
			    			if(requestMapping.value()[0].contains(methodName)){
			    				final WebUtil wu = new WebUtil(request, response);
			    				 SysLog sysLog = new SysLog();
				       			 sysLog.setIpAddress(NetworkUtil.getIpAddress(request));
				       			 try {
				       				sysLog.setUrl(wu.request.getRequestURI());
				       				sysLog.setIpArea(IPUtils.getAddressByIP(wu.getIpAddr()));
				       				AdminUser adminUser = (AdminUser) wu.getSessionAttr("adminUser");
				       				Member member = (Member) wu.getSessionAttr("member");
				       				if(adminUser!=null){
				       					sysLog.setOperator(adminUser.getRealName()+":"+adminUser.getUserName());
				       				}else if(member!=null){
				       					sysLog.setOperator("前台会员:("+member.getId()+")"+member.getNickName());
				       				}else{
				       					sysLog.setOperator("游客");
				       				}
				       				sysLog.setLogDate(DateUtils.getNow());
				       				sysLog.setActionName(anoSysLog.actionName());
				       				LogUtils.info("sysLog:"+sysLog.toString());
				       				logS.persist(sysLog);
				       			 } catch (Exception e) {
				       				e.printStackTrace();
				       			 }
			    			}
			    		}
					} 
		    	}
			}
		}catch(Exception e){
			LogUtils.error("拦截器有异常",e);
			e.printStackTrace();
		}
	}
	
	/**
	 * 第三执行  
     * 在DispatcherServlet完全处理完请求后被调用   
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()  
     */ 
	@Override
	public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object object, Exception e)
			throws Exception {
		
	}
}

